﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Isis.Helpers.Impl;
using Isis.Interfaces;
using Isis.Model;
using Isis.Views;

namespace Isis.Controllers
{
    public class FilesController : IControlPanelController
    {
        private readonly string _basePath;
        private readonly TableRenderingHelper _tableHelper;

        public FilesController(string basePath)
        {
            _basePath = basePath;
            _tableHelper = new TableRenderingHelper();
        }

        public ControllerTab Tab
        {
            get { return new ControllerTab("Files"); }
        }

        public string Action { get; set; }

        public string Parameter { get; set; }

        public IEnumerable<string> SubTabs
        {
            get { return new[] {"Overview", "Assembly Info", "File Info"}; }
        }

        public void Render(TextWriter writer)
        {
            var pageLayoutWriter = new PageLayoutWriter(Tab.Title, Action, new ControllerRepository(), _basePath);
            pageLayoutWriter.RenderPage(writer, RenderContent);
        }

        public void RenderContent(TextWriter writer)
        {
            switch (Action)
            {
                case "assembly_info":
                    RenderAssemblyInfoTable(writer);
                    break;
                case "file_info":
                    RenderFileInfoTable(writer);
                    break;
                case "overview":
                default:
                    RenderOverviewTable(writer);
                    break;
            }
        }

        private void RenderOverviewTable(TextWriter writer)
        {
            writer.Write(_tableHelper.RenderTableHeader("Overview"));
            var fileHelper = new FileDetailsHelper();
            FileDetails[] files = fileHelper.ListApplicationFolderFiles();
            int totalFiles = files.Count();
            long totalSizeBytes = files.Sum(f => f.SizeBytes);

            var assemblyHelper = new AssemblyDetailsHelper();
            AssemblyDetails[] assemblies = assemblyHelper.ListApplicationFolderFiles();
            int totalAssemblies = assemblies.Count();
            int totalDebugAssemblies = assemblies.Count(a => a.IsDebugBuild);


            writer.Write(_tableHelper.RenderRow(new[] {"Total Files: ", totalFiles.ToString()}));
            writer.Write(_tableHelper.RenderRow(new[] {"Total File Size (bytes): ", totalSizeBytes.ToString("#,#")}));
            writer.Write(_tableHelper.RenderRow(new[] { "Total Assemblies", totalAssemblies.ToString() }));

            string css = "";
            if (totalDebugAssemblies > 0)
            {
                css = "dbg";
            }
            writer.Write(_tableHelper.RenderRow(new[]
                                                    {
                                                        new TableCell() {Contents = "Debug Assemblies", CssClass = css},
                                                        new TableCell()
                                                            {Contents = totalDebugAssemblies.ToString(), CssClass = css}
                                                    }));
            writer.Write("</table>");
        }

        private void RenderFileInfoTable(TextWriter writer)
        {
            var fileHelper = new FileDetailsHelper();

            var sb = new StringBuilder();

            try
            {
                FileDetails[] files = fileHelper.ListApplicationFolderFiles();

                if (files.Any())
                {
                    sb.Append(_tableHelper.RenderTableHeader("Files"));
                    sb.Append(_tableHelper.RenderHeaderRow(new[] {"File Name", "Size", "Date Modified"}));

                    foreach (FileDetails file in files)
                    {
                        sb.AppendLine(
                            _tableHelper.RenderRow(new[]
                                                       {
                                                           file.Name,
                                                           file.SizeBytes.ToString("#,#"),
                                                           file.LastWriteTime.ToString()
                                                       }));
                    }

                    sb.Append("</table>");
                }
            }
            catch (Exception)
            {
                writer.Write("<p>Files unavailable</p>");
                return;
            }

            writer.Write(sb.ToString());
        }

        private void RenderAssemblyInfoTable(TextWriter writer)
        {
            var assemblyHelper = new AssemblyDetailsHelper();
            var sb = new StringBuilder();

            try
            {
                AssemblyDetails[] assemblies = assemblyHelper.ListApplicationFolderFiles();

                if (assemblies.Any())
                {
                    sb.Append(_tableHelper.RenderTableHeader("Assemblies"));
                    sb.Append(_tableHelper.RenderHeaderRow(new[] {"Assembly Name", "Version", "Debug Build?"}));

                    foreach (AssemblyDetails assembly in assemblies)
                    {
                        string css = "";
                        bool isDebug = assembly.IsDebugBuild;
                        if (isDebug)
                        {
                            css = "dbg";
                        }

                        sb.AppendLine(
                            _tableHelper.RenderRow(new[]
                                                       {
                                                           new TableCell {Contents = assembly.Name},
                                                           new TableCell {Contents = assembly.VersionString},
                                                           new TableCell
                                                               {
                                                                   Contents = assembly.IsDebugBuild.ToString(),
                                                                   CssClass = css
                                                               }
                                                       }));
                    }

                    sb.Append("</table>");
                }
            }
            catch (Exception)
            {
                writer.Write("<p>Assemblies unavailable</p>");
                return;
            }

            writer.Write(sb.ToString());
        }
    }
}